package com.wsn.mongodb.mongodbdemo.template;

import com.mongodb.client.MongoCollection;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.wsn.mongodb.mongodbdemo.entity.User;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Scanner;

/**
 * @Description: Mongo模板工具类
 * @ClassName: MongoTemplateUtil
 * @Author: weisn
 * @Date: 2022/5/20 14:59
 * @Version: 1.0
 */
@Component
public class MongoTemplateUtil {
    @Autowired
    private MongoTemplate mongoTemplate;


    /**
     * 创建集合
     *
     * @param collectionName: 集合名称
     * @author weisn
     * @date 2022/5/20 15:34
     * @see MongoCollection< Document>
     */
    public MongoCollection<Document> createCollection(String collectionName) {
        return mongoTemplate.createCollection(collectionName);
    }


    /**
     * 删除集合
     *
     * @param collectionName: 集合名称
     * @author weisn
     * @date 2022/5/20 15:33
     */
    public void deleteCollectionByName(String collectionName) {
        mongoTemplate.dropCollection(collectionName);
    }

    /**
     * 保存文档
     *
     * @param objectToSave: 保存对象
     * @author weisn
     * @date 2022/5/20 15:53
     * @see T
     */
    public <T> T insert(T objectToSave) {
        return mongoTemplate.save(objectToSave);
    }
    /**
     * 保存文档
     *
     * @param objectToSave: 保存对象
     * @author weisn
     * @date 2022/5/20 15:53
     * @see T
     */
    public <T> T insert(T objectToSave,String collectionName ) {
        return mongoTemplate.save(objectToSave,collectionName);
    }

    /**
     * 删除信息
     *
     * @author weisn
     * @date 2022/5/20 16:20
     * @see Long
     */
    public Long remove(Query query, Class<?> entityClass) {
        DeleteResult remove = mongoTemplate.remove(query, entityClass);
        return remove.getDeletedCount();
    }

    /**
     * 删除信息
     *
     * @author weisn
     * @date 2022/5/20 16:20
     * @see Long
     */
    public Long remove(Query query, Class<?> entityClass, String collectionName) {
        DeleteResult remove = mongoTemplate.remove(query, entityClass, collectionName);
        return remove.getDeletedCount();
    }

    //条件删除
    public void deleteUserByQuery() {
        //条件删除
        DeleteResult deleteResult = mongoTemplate.remove(Query.query(Criteria.where("name").is("xinan")), User.class);
    }

    //1、更新符合条件的第一条数据
    void updateFirst() {
        Update update = new Update();
        update.set("salary", 444.4);
        mongoTemplate.updateFirst(Query.query(Criteria.where("name").is("chenke")), update, User.class);
        List<User> user = mongoTemplate.find(Query.query(Criteria.where("name").is("chenke")), User.class);
        System.out.println(user);
    }

    //2、更新符合条件的所有数据
    public void updateMulti() {
        Update update = new Update();
        update.set("salary", 333.4);
        mongoTemplate.updateMulti(Query.query(Criteria.where("name").is("chenke2")), update, User.class);
        List<User> users = mongoTemplate.find(Query.query(Criteria.where("name").is("chenke2")), User.class);
        users.forEach(System.out::println);
    }

    //3、更新符合条件的第一条数据，没有符合条件的将插入
    public void upsert() {
        Update update = new Update();
        update.setOnInsert("id", 13);
        update.setOnInsert("name", "chenke4");
        update.set("salary", 42222.4);
        update.setOnInsert("birthday", new Date());
        UpdateResult updateResult = mongoTemplate.upsert(Query.query(Criteria.where("name").is("chenke4")), update, User.class);
        List<User> users = mongoTemplate.find(Query.query(Criteria.where("name").is("chenke3")), User.class);
        users.forEach(System.out::println);
    }

    //1、查询所有
    public void findAllUser() {
        List<User> user = mongoTemplate.findAll(User.class);
        user.forEach(System.out::println);
    }

    //根据id查询
    public <T> T  findById(Object id, Class<T> entityClass) {
        return mongoTemplate.findById(id, entityClass);
    }


    public <T> List<T> find(Query query, Class<T> entityClass) {
        return mongoTemplate.find(query, entityClass);
    }
    public <T> List<T> find(Query query, Class<T> entityClass, String collectionName) {
        return mongoTemplate.find(query, entityClass,collectionName);
    }

    //and

    public void findUserByQueryAnd() {
        Scanner scanner = new Scanner(System.in);
        String userName = scanner.nextLine();
        Query queryAnd = Query.query(Criteria.where("name").is(userName).and("id").is(0));
        List<User> users = mongoTemplate.find(queryAnd, User.class);
        users.forEach(System.out::println);
    }

    //or

    public void findUserByQueryOr() {
        Scanner scanner = new Scanner(System.in);
        String userName = scanner.nextLine();
        Query queryAnd = Query.query(Criteria.where("name").is(userName).and("id").is(0));
        List<User> users = mongoTemplate.find(queryAnd, User.class);
        users.forEach(System.out::println);
    }

    //or and

    public void findUserByQueryOrAnd() {
        Scanner scanner = new Scanner(System.in);
        String userName = scanner.nextLine();
        //and or
        Criteria criteriaAndOr = new Criteria();
        criteriaAndOr.and("age").is(0).orOperator(Criteria.where("name").is(userName), Criteria.where("name").is(userName));
        List<User> users = mongoTemplate.find(Query.query(criteriaAndOr), User.class);
        users.forEach(System.out::println);
    }

    //Sort

    public void findUserByQuerySort() {
        Query querySort = new Query();
        querySort.with(Sort.by(Sort.Order.desc("salary")));
        List<User> users = mongoTemplate.find(querySort, User.class);
        users.forEach(System.out::println);
    }


    //limit

    public void findUserByQueryLimit() {
        Query queryLimit = new Query();
        queryLimit.with(Sort.by(Sort.Order.desc("salary"))).skip(0).limit(2);
        List<User> userLimit = mongoTemplate.find(queryLimit, User.class);
        userLimit.forEach(System.out::println);
    }

    //count

    public void findUserCount() {
        //总条数
        long count = mongoTemplate.count(new Query(), User.class);
        System.out.println(count);
    }

    //distinct

    void findUserDistinct() {
        //去重
        List<Double> salary = mongoTemplate.findDistinct(new Query(), "salary", User.class, Double.class);
    }

    //basicQuery JOSN
    public void basicQuery() {
        BasicQuery basicQuery = new BasicQuery("{name:'string'}");
        List<User> users = mongoTemplate.find(basicQuery, User.class);
        users.forEach(System.out::println);
    }


}
